package com.rockcent.mall.lib.repository;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.SQLObjectDoing;
import com.rockcent.common.common.SQLPageDoing;
import com.rockcent.mall.lib.dto.ChannelProductDto;
import com.rockcent.mall.lib.dto.ProductDto;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

/**
 * Created by zhangjh on 2016/10/26.
 */
@Repository
public class ChannelProductRepositoryImpl implements ChannelProductRepositoryCustom {

    private static final Logger log = LoggerFactory.getLogger(ChannelProductRepositoryImpl.class);

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public PageResult<ProductDto> listProductByMerchantIdAndMallIdAndChannelId(Long merchantId, Long mallId, Long channelId, String scope, PageResult pageResult) {

        SQLPageDoing<ProductDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("SELECT %s from  product_categories  pc");
            sql.append(" LEFT JOIN  product p ON pc.product_id=p.id or pc.product_id=p.market_id");
            sql.append(" LEFT JOIN  product_quantity pq ON p.product_quantity_id=pq.id");
            sql.append(" left join category c on c.id=pc.category_id");
            sql.append(" WHERE p.mall_id=:mallId AND p.merchant_id=:merchantId and p.status = 'SELLING' and pq.quantity > 0");

            sql.append(" AND c.parent_id IN(select c.id from  category c where c.parent_id in(SELECT cc.category_id FROM channel_category cc where cc.channel_product_types_id=:channelId))");

            sql.append(" AND p.id not in(select pc.product_id from channel_product pc where pc.is_delete='NO' and  pc.channel_id=:productChannelId)");

            params.put("merchantId", merchantId);
            params.put("mallId", mallId);
            params.put("channelId", channelId);
            params.put("productChannelId", channelId);

            if ("self".equals(scope)) {
                sql.append(" AND p.market_id  IN NULL");
            }
            if ("share".equals(scope)) {
                sql.append(" AND p.market_id IN NOT NULL");
            }

            fields.append("DISTINCT p.id,p.name,p.base_price,p.barcode,p.promote_url,pq.quantity,p.sell_price,p.date_disabled,p.market_id");

        };

        return doing.go(pageResult,ProductDto.class,objectMapper,jdbcTemplate,log);

    }

    @Override
    public PageResult<ChannelProductDto> findByChannelIdAndScope(Long channelId, String productName, String scope,PageResult pageResult) {
        SQLPageDoing<ChannelProductDto> doing = (sql, fields, params, typeReferenceMap) -> {

            sql.append("SELECT %s FROM `channel_product` cp");
            sql.append(" LEFT JOIN product p ON cp.product_id=p.id");
            sql.append(" LEFT JOIN  product_quantity pq ON p.product_quantity_id=pq.id");
            sql.append(" WHERE cp.is_delete='NO' AND channel_id=:channelId");

            if (StringUtils.isNotBlank(productName)) {
                sql.append(" AND (p.name like :productName OR p.id like :barCode)");
                params.put("productName", "%" + productName + "%");
                params.put("barCode", "%" + productName + "%");
            }

            if ("self".equals(scope)) {
                sql.append(" AND p.market_id is NULL");
            }
            if ("share".equals(scope)) {
                sql.append(" AND p.market_id is NOT NULL");
            }
            params.put("channelId", channelId);
            fields.append("cp.id,cp.product_id,p.name as productName,p.barcode,p.promote_url,pq.quantity,p.sell_price,p.date_disabled,p.market_id,p.status,p.base_price,p.logo_url,p.type,p.share_fee");
        };
        return doing.go(pageResult,ChannelProductDto.class,objectMapper,jdbcTemplate,log);
    }

    @Override
    public Long productCountByChannelId(Long channelId) {
        SQLObjectDoing<Long> result = (sql, fields, params, typeReferenceMap) -> {
            sql.append("select %s from channel_product cp left join product p ON cp.product_id = p.id where cp.is_delete = 'NO' AND channel_id = :channelId");
            params.put("channelId", channelId);
            fields.append("count(1)");
        };
        return result.go(Long.class, jdbcTemplate, log, objectMapper);
    }


}
